home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
src
/
haeberli
/
libgutil
/
objlib.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
15KB
|
755 lines
/*
* Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
/*
* obj -
* Some utilities for reading a writing geometric objects.
*
* Paul Haeberli - 1985
*/
#include "obj.h"
static tokentofile();
static tofile();
static int dowriteattrs;
static int dowritebinary;
#define ATTR_TOKEN 0
#define POINT_TOKEN 0
#define LINE_TOKEN 1
#define LOOP_TOKEN 2
#define POLY_TOKEN 3
/*
* fast point alloc and free
*
*/
#define NINCHUNK 100
static point *fpnts;
static point *pntmalloc()
{
point *p;
int i;
if(!fpnts) {
p = (point *)mymalloc(NINCHUNK*sizeof(point));
for(i=0; i<NINCHUNK; i++)
freepnt(p++);
}
p = fpnts;
fpnts = fpnts->next;
return p;
}
freepnt(pnt)
point *pnt;
{
if( pnt ) {
pnt->next = fpnts;
fpnts = pnt;
}
}
writeattrs(f)
int f;
{
dowriteattrs = f;
}
writebinary(f)
int f;
{
dowritebinary = f;
}
writeobj(outf,obj)
FILE *outf;
object *obj;
{
if(dowritebinary) {
putstr(outf,"binarygeom");
putnewline(outf);
while(obj) {
if(dowriteattrs && obj->attr)
putattr(outf,obj->attr);
if(obj->type == OBJ_POINTS) {
tokentofile(outf,POINT_TOKEN);
putpoints(outf,obj->points);
} else if(obj->type == OBJ_LINE) {
tokentofile(outf,LINE_TOKEN);
putpoints(outf,obj->points);
} else if(obj->type == OBJ_LOOP) {
tokentofile(outf,LOOP_TOKEN);
putpoints(outf,obj->points);
} else if(obj->type == OBJ_POLYGON) {
tokentofile(outf,POLY_TOKEN);
putpoints(outf,obj->points);
} else
printf("writeobj: blat\n");
obj = obj->next;
}
} else {
while(obj) {
if(dowriteattrs && obj->attr)
putattr(outf,obj->attr);
if(obj->type == OBJ_POINTS) {
putstr(outf,"beginpoints");
putnewline(outf);
putpoints(outf,obj->points);
putstr(outf,"endpoints");
putnewline(outf);
} else if(obj->type == OBJ_LINE) {
putstr(outf,"beginline");
putnewline(outf);
putpoints(outf,obj->points);
putstr(outf,"endline");
putnewline(outf);
} else if(obj->type == OBJ_LOOP) {
putstr(outf,"beginloop");
putnewline(outf);
putpoints(outf,obj->points);
putstr(outf,"endloop");
putnewline(outf);
} else if(obj->type == OBJ_POLYGON) {
putstr(outf,"beginpoly");
putnewline(outf);
putpoints(outf,obj->points);
putstr(outf,"endpoly");
putnewline(outf);
} else
printf("writeobj: blat\n");
obj = obj->next;
}
}
}
putpoints(outf,pnt)
FILE *outf;
point *pnt;
{
if(dowritebinary) {
while(pnt) {
if(dowriteattrs && pnt->attr)
putattr(outf,pnt->attr);
tokentofile(outf,ATTR_TOKEN);
tofile(outf,&pnt->x,3*sizeof(float));
pnt = pnt->next;
}
} else {
while(pnt) {
if(dowriteattrs && pnt->attr)
putattr(outf,pnt->attr);
putstr(outf,"\tpnt");
putfloat(outf,pnt->x);
putfloat(outf,pnt->y);
putfloat(outf,pnt->z);
putnewline(outf);
pnt = pnt->next;
}
}
}
static tofile(outf,data,len)
FILE *outf;
char *data;
int len;
{
fwrite(data,1,len,outf);
}
static tokentofile(outf,token)
FILE *outf;
int token;
{
fwrite(&token,1,sizeof(int),outf);
}
putattr(outf,attr)
FILE *outf;
attribs *attr;
{
if(dowritebinary) {
tokentofile(outf,ATTR_TOKEN);
tofile(outf,attr,6*sizeof(float));
} else {
putstr(outf,"\tattr");
putfloat(outf,attr->r);
putfloat(outf,attr->g);
putfloat(outf,attr->b);
putfloat(outf,attr->nx);
putfloat(outf,attr->ny);
putfloat(outf,attr->nz);
putnewline(outf);
}
}
moveobj(obj,dx,dy,dz)
object *obj;
float dx, dy, dz;
{
point *pnt;
while(obj) {
pnt = obj->points;
while(pnt) {
pnt->x += dx;
pnt->y += dy;
pnt->z += dz;
pnt = pnt->next;
}
obj = obj->next;
}
}
object *newobj()
{
object *obj;
obj = (object *)mymalloc(sizeof(object));
obj->next = NULL;
obj->type = OBJ_LINE;
obj->attr = NULL;
obj->points = NULL;
return obj;
}
attribs *newattr()
{
attribs *attr;
attr = (attribs *)mymalloc(sizeof(attribs));
attr->r = 0.0;
attr->g = 0.0;
attr->b = 0.0;
attr->nx = 0.0;
attr->ny = 0.0;
attr->nz = 0.0;
}
freeattr(attr)
attribs *attr;
{
free(attr);
}
attribs *cloneattr(attr)
attribs *attr;
{
attribs *cattr;
cattr = (attribs *)mymalloc(sizeof(attribs));
*cattr = *attr;
return cattr;
}
point *newpnt(x,y,z)
float x, y, z;
{
point *pnt;
pnt = pntmalloc();
pnt->next = NULL;
pnt->type = PNT_SQUARE;
pnt->attr = NULL;
pnt->x = x;
pnt->y = y;
pnt->z = z;
return pnt;
}
point *clonepnt(pnt)
point *pnt;
{
point *cpnt;
cpnt = pntmalloc();
cpnt->next = NULL;
cpnt->type = pnt->type;
if(pnt->attr)
cpnt->attr = cloneattr(pnt->attr);
else
cpnt->attr = NULL;
cpnt->x = pnt->x;
cpnt->y = pnt->y;
cpnt->z = pnt->z;
return cpnt;
}
addpoint(obj,pnt)
object *obj;
point *pnt;
{
point *cpnt;
pnt->next = NULL;
if(obj->points) {
cpnt = obj->points;
while(cpnt->next)
cpnt = cpnt->next;
cpnt->next = pnt;
} else
obj->points = pnt;
}
addobject(obj,nobj)
object *obj, *nobj;
{
object *cobj;
if(obj->next) {
cobj = obj->next;
while(cobj->next)
cobj = cobj->next;
cobj->next = nobj;
} else
obj->next = nobj;
}
freepnts(pnt)
point *pnt;
{
point *npnt;
while(pnt) {
npnt = pnt->next;
if(pnt->attr)
freeattr(pnt->attr);
freepnt(pnt);
pnt = npnt;
}
}
freeobj(obj)
object *obj;
{
object *nobj;
while(obj) {
nobj = obj->next;
freepnts(obj->points);
if(obj->attr)
free(obj->attr);
free(obj);
obj = nobj;
}
}
object *objfromfile(name)
char *name;
{
object *obj;
FILE *inf;
inf = fopen(name,"r");
if(!inf) {
fprintf(stderr,"objfromfile: can't open file %s\n",name);
return 0;
}
obj = getobj(inf);
fclose(inf);
return obj;
}
objtofile(name,obj)
char *name;
object *obj;
{
FILE *of;
of = fopen(name,"w");
if(!of) {
fprintf(stderr,"objtofile: can't open file %s\n",name);
return 0;
}
writeobj(of,obj);
fclose(of);
}
object *getobj(inf)
FILE *inf;
{
float x, y, z;
object *objlist;
object *curobj;
point *npnt;
attribs *attr;
char buf[512];
attr = 0;
objlist = NULL;
while(getstr(inf,buf)) {
if(*buf == 0) {
;
} else if(strcmp(buf,"beginpoly") == 0) {
getnewline(inf);
curobj = newobj();
curobj->type = OBJ_POLYGON;
curobj->next = objlist;
curobj->attr = attr;
objlist = curobj;
while(getstr(inf,buf)) {
if(strcmp(buf,"pnt") == 0) {
x = getfloat(inf);
y = getfloat(inf);
z = getfloat(inf);
getnewline(inf);
npnt = newpnt(x,y,z);
npnt->attr = attr;
addpoint(curobj,npnt);
} else if(strcmp(buf,"endpoly") == 0) {
getnewline(inf);
break;
} else if(strcmp(buf,"attr") == 0) {
attr = newattr();
attr->r = getfloat(inf);
attr->g = getfloat(inf);
attr->b = getfloat(inf);
attr->nx = getfloat(inf);
attr->ny = getfloat(inf);
attr->nz = getfloat(inf);
getnewline(inf);
} else
printf("getobj: bblat\n");
}
} else if(strcmp(buf,"beginline") == 0) {
getnewline(inf);
curobj = newobj();
curobj->type = OBJ_LINE;
curobj->next = objlist;
objlist = curobj;
while(getstr(inf,buf)) {
if(strcmp(buf,"pnt") == 0) {
x = getfloat(inf);
y = getfloat(inf);
z = getfloat(inf);
getnewline(inf);
npnt = newpnt(x,y,z);
npnt->attr = attr;
addpoint(curobj,npnt);
} else if(strcmp(buf,"endline") == 0) {
getnewline(inf);
break;
} else if(strcmp(buf,"attr") == 0) {
attr = newattr();
attr->r = getfloat(inf);
attr->g = getfloat(inf);
attr->b = getfloat(inf);
attr->nx = getfloat(inf);
attr->ny = getfloat(inf);
attr->nz = getfloat(inf);
getnewline(inf);
} else
printf("getobj: bblat\n");
}
} else if(strcmp(buf,"beginloop") == 0) {
getnewline(inf);
curobj = newobj();
curobj->type = OBJ_LOOP;
curobj->next = objlist;
objlist = curobj;
while(getstr(inf,buf)) {
if(strcmp(buf,"pnt") == 0) {
x = getfloat(inf);
y = getfloat(inf);
z = getfloat(inf);
getnewline(inf);
npnt = newpnt(x,y,z);
npnt->attr = attr;
addpoint(curobj,npnt);
} else if(strcmp(buf,"endloop") == 0) {
getnewline(inf);
break;
} else if(strcmp(buf,"attr") == 0) {
attr = newattr();
attr->r = getfloat(inf);
attr->g = getfloat(inf);
attr->b = getfloat(inf);
attr->nx = getfloat(inf);
attr->ny = getfloat(inf);
attr->nz = getfloat(inf);
getnewline(inf);
} else
printf("getobj: bblat\n");
}
} else if(strcmp(buf,"beginpoints") == 0) {
getnewline(inf);
curobj = newobj();
curobj->type = OBJ_POINTS;
curobj->next = objlist;
objlist = curobj;
while(getstr(inf,buf)) {
if(strcmp(buf,"pnt") == 0) {
x = getfloat(inf);
y = getfloat(inf);
z = getfloat(inf);
getnewline(inf);
npnt = newpnt(x,y,z);
npnt->attr = attr;
addpoint(curobj,npnt);
} else if(strcmp(buf,"endpoints") == 0) {
getnewline(inf);
break;
} else if(strcmp(buf,"attr") == 0) {
attr = newattr();
attr->r = getfloat(inf);
attr->g = getfloat(inf);
attr->b = getfloat(inf);
attr->nx = getfloat(inf);
attr->ny = getfloat(inf);
attr->nz = getfloat(inf);
getnewline(inf);
} else
printf("getobj: bblat\n");
}
} else if(strcmp(buf,"attr") == 0) {
attr = newattr();
attr->r = getfloat(inf);
attr->g = getfloat(inf);
attr->b = getfloat(inf);
attr->nx = getfloat(inf);
attr->ny = getfloat(inf);
attr->nz = getfloat(inf);
getnewline(inf);
} else if(strcmp(buf,"binarygeom") == 0) {
printf("getobj: binary geom\n");
} else
printf("getobj: abalt\n");
}
return objlist;
}
object *twixtobj(obj1, obj2)
object *obj1, *obj2;
{
point *pnt1, *pnt2;
point *next1, *next2;
object *objlist;
object *curobj;
int more;
objlist = curobj = 0;
while(obj1 && obj2) {
pnt1 = obj1->points;
pnt2 = obj2->points;
while(1) {
if(obj1->type==OBJ_LINE) {
if (!(pnt1 && pnt2 && pnt1->next && pnt2->next))
break;
} else {
if (!(pnt1 && pnt2))
break;
}
if(!objlist) {
objlist = curobj = newobj();
} else {
curobj->next = newobj();
curobj = curobj->next;
}
if(obj1->type == OBJ_POINTS)
curobj->type = OBJ_LINE;
else
curobj->type = OBJ_POLYGON;
next1 = pnt1->next;
if(!next1)
next1 = obj1->points;
next2 = pnt2->next;
if(!next2)
next2 = obj2->points;
addpoint(curobj,clonepnt(pnt1));
addpoint(curobj,clonepnt(pnt2));
pnt1 = pnt1->next;
pnt2 = pnt2->next;
if(obj1->type != OBJ_POINTS) {
addpoint(curobj,clonepnt(next2));
addpoint(curobj,clonepnt(next1));
}
}
obj1 = obj1->next;
obj2 = obj2->next;
}
return objlist;
}
applyobj(obj,func)
object *obj;
int (*func)();
{
point *apnt;
while(obj) {
apnt = obj->points;
while(apnt) {
(func)(apnt);
apnt = apnt->next;
}
obj = obj->next;
}
}
objdomain(obj,px1,px2,py1,py2,pz1,pz2)
object *obj;
float *px1, *px2;
float *py1, *py2;
float *pz1, *pz2;
{
point *apnt;
float x1, x2;
float y1, y2;
float z1, z2;
x1 = 1000000.0;
x2 = -1000000.0;
y1 = 1000000.0;
y2 = -1000000.0;
z1 = 1000000.0;
z2 = -1000000.0;
while(obj) {
apnt = obj->points;
while (apnt) {
if (apnt->x > x2) x2 = apnt->x;
if (apnt->x < x1) x1 = apnt->x;
if (apnt->y > y2) y2 = apnt->y;
if (apnt->y < y1) y1 = apnt->y;
if (apnt->z > z2) z2 = apnt->z;
if (apnt->z < z1) z1 = apnt->z;
apnt = apnt->next;
}
obj = obj->next;
}
*px1 = x1; *px2 = x2;
*py1 = y1; *py2 = y2;
*pz1 = z1; *pz2 = z2;
}
object *cloneobj(obj)
object *obj;
{
object *robj, *cobj;
point *pnt, *cpnt;
cobj = robj = NULL;
while(obj) {
if(cobj) {
cobj->next = newobj();
cobj = cobj->next;
} else
cobj = robj = newobj();
cobj->type = obj->type;
if(obj->points) {
pnt = obj->points;
cpnt = clonepnt(pnt);
cpnt->type = pnt->type;
cobj->points = cpnt;
pnt = pnt->next;
while(pnt) {
cpnt->next = clonepnt(pnt);
cpnt = cpnt->next;
cpnt->type = pnt->type;
pnt = pnt->next;
}
}
obj = obj->next;
}
return robj;
}
evertobj(obj)
object *obj;
{
point *pntlist, *pnt, *epnt;;
while(obj) {
if(obj->points) {
pntlist = pnt = obj->points;
obj->points = 0;
while(pnt) {
epnt = clonepnt(pnt);
epnt->next = obj->points;
obj->points = epnt;
pnt = pnt->next;
}
freepnts(pntlist);
}
obj = obj->next;
}
}
objstats(obj)
object *obj;
{
int polys, lines, loops, pointlists, points;
polys = loops = lines = pointlists = points = 0;
while(obj) {
if(obj->type == OBJ_POINTS) {
pointlists++;
points += pntcount(obj);
} else if(obj->type == OBJ_LINE) {
lines++;
points += pntcount(obj);
} else if(obj->type == OBJ_LOOP) {
loops++;
points += pntcount(obj);
} else if(obj->type == OBJ_POLYGON) {
polys++;
points += pntcount(obj);
}
obj = obj->next;
}
printf("objstat: %d polys %d loops %d lines %d pntlists. %d tot pnts\n",
polys,loops,lines,pointlists,points);
}
pntcount(obj)
object *obj;
{
point *pnt;
int n;
pnt = obj->points;
n = 0;
while(pnt) {
n++;
pnt = pnt->next;
}
return n;
}
stripobj(obj)
object *obj;
{
point *pnt;
while(obj) {
if(obj->attr) {
freeattr(obj->attr);
obj->attr = 0;
}
pnt = obj->points;
while(pnt) {
if(pnt->attr) {
freeattr(pnt->attr);
pnt->attr = 0;
}
pnt = pnt->next;
}
obj = obj->next;
}
}